/*
 * Copyright (c) 2007-2008, Thomas Krause (tho.krause@gmail.com)
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of gidoo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without specific
 *       prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.gidoo.cms.editor.resources;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.gidoo.cms.GidooCMS;
import org.gidoo.cms.data.Folder;
import org.gidoo.cms.data.Resource;
import org.gidoo.cms.dbconnection.DatabaseConnectionException;
import org.gidoo.cms.dbconnection.Persistance;
import org.gidoo.cms.editor.EditorPage;
import org.gidoo.cms.login.GidooCMSAuthenticatedWebSession;
import org.gidoo.cms.helper.ResourceDownloadLink;

/**
 * 
 * @author thomas
 */
public class ResourcesPanel extends Panel
{
  Folder theFolder;
  EditorPage theParent;
  
  Form formMain;
  FileUploadField fileUpload;
  AutoCompleteTextField txtMIME;
  Button btAdd;
  
  ListView lsvFiles;
  
  public final String[] knownMIMETypes = new String[]
  {
    "application/gtar",
    "application/gzip",
    "application/pdf",
    "application/postscript",
    "application/zip",
    "image/gif",
    "image/jpeg",
    "image/png",
    "text/plain",
    "text/xml",
    "video/mpeg"
  };
  
  public ResourcesPanel(String id, Folder folder, EditorPage parent)
  {
    super(id);
    this.theFolder = folder;
    this.theParent = parent;
    
    formMain = new Form("formMain")
    {

      @Override
      protected void onSubmit()
      {
        uploadFile();
      }
      
    };
    fileUpload = new FileUploadField("fileUpload");
    fileUpload.setRequired(true);
    
    txtMIME = new AutoCompleteTextField("txtMIME") {

      @Override
      protected Iterator getChoices(String input)
      {
        LinkedList<String> result = new LinkedList<String>();
        for(String s : knownMIMETypes)
        {
          if(s.contains(input))
          {
            result.add(s);
          }
        }
        return result.iterator();
      }
    };
    txtMIME.setModel(new Model(""));
    
    btAdd = new Button("btAdd");
    btAdd.setModel(new Model(getString("add")));
    
    formMain.add(fileUpload);
    formMain.add(txtMIME);
    formMain.add(btAdd);
    
    formMain.setMultiPart(true);
    
    lsvFiles = new ListView("lsvFiles") {

      @Override
      protected void populateItem(ListItem item)
      {        
        createListItem(item);
      }
    };
  
    formMain.add(lsvFiles);
    formMain.add(new UploadProgressBar("uploadProgress", formMain));
    
    add(formMain);
    
    if(theFolder == null)
    {
      formMain.setVisible(false);
    }
    else
    {
      lsvFiles.setList(theFolder.getResources());    
    }
    
  }

  private void createListItem(ListItem item)
  {   
    final Resource res = theFolder.getResources().get(item.getIndex());
   
    ResourceDownloadLink lnkFileDownload = new ResourceDownloadLink("lnkFileDownload", res);
    item.add(lnkFileDownload);

    String ps = res.getIsPublished() ? getString("published") : getString("notpublished");
    Label lblFileCaption = new Label("lblFileCaption", 
      new Model(res.getName() + " (" + res.getType() + ", " + ps + ")"));

    lnkFileDownload.add(lblFileCaption);

    Link lnkDelete = new Link("lnkDelete", new Model("delete"))
    {

      @Override
      public void onClick()
      {
        deleteResource(res);
      }

    };

    item.add(lnkDelete);
        
  }
  
  private void deleteResource(Resource res)
  {
    try
    {
      File resFile = res.getFile((GidooCMS) getApplication());
      if(!resFile.delete())
      {
        warn(getString("filenotdeleted")  + " " + resFile.getAbsolutePath());
      }
      ((GidooCMS) getApplication()).getDb().remove(res);      
      if(theFolder.getResources() != null)
        theFolder.getResources().remove(res);
      
    }
    catch (DatabaseConnectionException ex)
    {
      Logger.getLogger(ResourcesPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("dberror"));
    }
  }
  
  private void uploadFile()
  {
    {
      try
      {
        if (theFolder.getResources() == null)
        {
          theFolder.setResources(new LinkedList<Resource>());
        }
        FileUpload u = fileUpload.getFileUpload();
        String mime = txtMIME.getModelObjectAsString();
        if (mime == null || "".equals(mime))
        {
          mime = u.getContentType();
        }
        GidooCMSAuthenticatedWebSession session = (GidooCMSAuthenticatedWebSession) getSession();
        Resource res = new Resource();
        res.setName(u.getClientFileName());
        res.setType(mime);
        res.setIsPublished(false);
        res.setCreatedBy(session.getUserInfo());
        res.setCreationTime(new Date());
        res.setFolder(theFolder);
        ((GidooCMS) getApplication()).getDb().persist(res);
        theFolder.getResources().add(res);
       
        File outputFile = res.getFile((GidooCMS) getApplication());
       
        BufferedOutputStream out = null;
        BufferedInputStream in = null;
        try
        {
          out = new BufferedOutputStream(new FileOutputStream(outputFile));
          in = new BufferedInputStream(u.getInputStream());
          
          int b = in.read();
          while(b > -1)
          {
            out.write(b);
            b = in.read();
          }
          out.close();
          in.close();
          
        }
        catch (IOException ex)
        {
          Logger.getLogger(ResourcesPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally
        {
          try
          {
            out.close();
          }
          catch (IOException ex)
          {
            Logger.getLogger(ResourcesPanel.class.getName()).log(Level.SEVERE, null, ex);
          }
        }

        info(getString("wasadded"));
      }
      
      catch (DatabaseConnectionException ex)
      {
        Logger.getLogger(ResourcesPanel.class.getName()).log(Level.SEVERE, null, ex);
        error(getString("dberror"));
      }
    }
  }
  
  public void updateDataAndView(Folder folder, EditorPage parent)
  {
    this.theFolder = folder;
    this.theParent = parent;
    
    if(theFolder == null)
    {
      formMain.setVisible(false);
    }
    else
    {
      lsvFiles.setList(theFolder.getResources());    
    }
  }
  
}
